{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. _nb_cs:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cuckoo Search\n",
    "\n",
    "This class represents standard Cuckoo Search based on the explanation in the [\\[book\\]](https://doi.org/10.1016/B978-0-12-416743-8.00009-9) Nature-Inspired Optimization Algorithms by Xin-She Yang and his implementation of standard Cuckoo Search in Matlab on [\\[mathworks\\]](https://www.mathworks.com/matlabcentral/fileexchange/29809-cuckoo-search-cs-algorithm). The implementation is slightly different to the flow of the algorithm described in the book. The figures below describe the pseudocode of the algorithm from the book, and the flow of the implementation. The GRW stands for Global Random Walk by Levy Flight, and the LRW stands for Local Random Walk.\n",
    "\n",
    "1) **Initial Population:**: A starting population is sampled in the beginning. In this framework, this can be either a [Sampling](../operators/sampling.ipynb) object, which defines different initial sampling strategies, or `Population` where the `X` and `F` values are set, or a simple NumPy array (pop_size x n_var).\n",
    "\n",
    "2) **Evaluation:** It is executed using the problem defined to be solved.\n",
    "\n",
    "3) **Survival:** The survival mechanism used is by default the survival of the fittest for the Elitism.\n",
    "\n",
    "4) **Global Random Walk:** The global random walks use a step size that is generated based on Levy Flight Distribution. Every dimension will have its own randomly generated step size on every operation. The Global Random Walk can be done following the book which to randomly choose solution $x_{i}$ which will be modified by Global Random Walk resulting in $x'_i$ and replace a randomly chosen solution $x_{j}$, if $x'_{i}$ is better than $x_{j}$. However for simplicity sake, as also been done in the matlab implementation, $x'_{i}$ will be compared to $x_{i}, \\forall i$ in every iteration. \n",
    "\n",
    "5) **Local Random Walk:** After the Global Random Walk has been done, including the replacement after improvement, every nest $x_i$ has a $p_a$ probability to create new solution via Local Ranom Walk $x'_i = x_i + \\alpha_0*(x_j-x_k)$ with $x_j$ and $x_k$ are two different randomly selected nest. Afterwards, combine the old nests with the new generated nests via Local Random Walks. The size of the combined nests will be pop_size $\\leq$ combined_pop_size $\\leq 2$pop_size. Survival mechanism thus will be used to select a number of pop_size best nests.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"display: block;margin-left: auto;margin-right: auto;width: 60%;\">\n",
    "![cs_pseudocode](../resources/images/cuckoo_search_pseudocode.png)\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"display: block;margin-left: auto;margin-right: auto;width: 60%;\">\n",
    "![cs_flow](../resources/images/cuckoo_search_flow.png)\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "code": "algorithms/usage_ga.py",
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best solution found: \n",
      "X = [9.99994958e-01 9.99997291e-01 9.99999965e-01 9.99999953e-01\n",
      " 5.99188061e-04 1.00000000e+00 9.99999967e-01 9.99999956e-01\n",
      " 9.99999998e-01 2.00059057e+00 2.99999199e+00 2.99999946e+00\n",
      " 9.99992117e-01]\n",
      "F = [-13.00113408]\n"
     ]
    }
   ],
   "source": [
    "from pymoo.algorithms.so_cuckoo_search import CuckooSearch\n",
    "from pymoo.factory import get_problem\n",
    "from pymoo.optimize import minimize\n",
    "from pymoo.visualization.scatter import Scatter\n",
    "\n",
    "problem = get_problem(\"g01\")\n",
    "\n",
    "algorithm = CuckooSearch()\n",
    "\n",
    "res = minimize(problem, algorithm, seed=1, verbose=False)\n",
    "print(\"Best solution found: \\nX = %s\\nF = %s\" % (res.X, res.F))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### API"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. autofunction:: pymoo.algorithms.so_cuckoo_search.CuckooSearch\n",
    "    :noindex:"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Raw Cell Format",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
